package io.gitee.zhangbinhub.admin.oauth.controller.api

import io.gitee.zhangbinhub.acp.boot.exceptions.WebException
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.acp.cloud.annotation.AcpCloudDuplicateSubmission
import io.gitee.zhangbinhub.acp.core.common.CommonTools
import io.gitee.zhangbinhub.admin.common.api.OauthApi
import io.gitee.zhangbinhub.admin.common.vo.CustomerQueryPageVo
import io.gitee.zhangbinhub.admin.common.vo.InfoVo
import io.gitee.zhangbinhub.admin.oauth.bus.publish.RefreshEventPublish
import io.gitee.zhangbinhub.admin.oauth.constant.RuntimeConfigExpression
import io.gitee.zhangbinhub.admin.oauth.controller.openinner.OpenInnerRuntimeController
import io.gitee.zhangbinhub.admin.oauth.service.RuntimeConfigService
import io.gitee.zhangbinhub.admin.oauth.entity.RuntimeConfig
import io.gitee.zhangbinhub.admin.oauth.po.RuntimePo
import io.gitee.zhangbinhub.admin.oauth.po.RuntimeQueryPo
import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController
import io.gitee.zhangbinhub.admin.resource.server.vo.RuntimeConfigVo
import io.swagger.v3.oas.annotations.*
import io.swagger.v3.oas.annotations.responses.ApiResponse
import io.swagger.v3.oas.annotations.responses.ApiResponses
import io.swagger.v3.oas.annotations.tags.Tag
import jakarta.validation.Valid
import jakarta.validation.constraints.NotEmpty
import jakarta.validation.constraints.NotNull
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.domain.Page
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*

/**
 * @author zhang by 11/01/2019
 * @since JDK 11
 */
@Validated
@RestController
@RequestMapping(OauthApi.basePath)
@Tag(name = "运行参数配置")
class RuntimeController @Autowired
constructor(
    logAdapter: LogAdapter,
    private val openInnerRuntimeController: OpenInnerRuntimeController,
    private val runtimeConfigService: RuntimeConfigService,
    private val refreshEventPublish: RefreshEventPublish
) : BaseResourceServerController(logAdapter) {

    @Operation(summary = "新建参数信息", description = "参数名称、参数值、描述、状态")
    @ApiResponses(ApiResponse(responseCode = "201", description = "创建成功"))
    @PreAuthorize(RuntimeConfigExpression.runtimeAdd)
    @PutMapping(value = [OauthApi.runtimeConfig], produces = [MediaType.APPLICATION_JSON_VALUE])
    @AcpCloudDuplicateSubmission
    @Throws(WebException::class)
    fun add(@RequestBody @Valid runtimePo: RuntimePo): ResponseEntity<RuntimeConfig> =
        runtimeConfigService.doCreate(runtimePo).also {
            refreshEventPublish.doNotifyUpdateRuntime()
        }.let {
            ResponseEntity.status(HttpStatus.CREATED).body(it)
        }

    @Operation(summary = "删除指定的参数信息")
    @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过；"))
    @PreAuthorize(RuntimeConfigExpression.runtimeDelete)
    @DeleteMapping(value = [OauthApi.runtimeConfig], produces = [MediaType.APPLICATION_JSON_VALUE])
    fun delete(
        @Parameter(description = "id列表", required = true)
        @NotEmpty(message = "id不能为空")
        @NotNull(message = "id不能为空")
        @RequestBody
        idList: MutableList<String>
    ): ResponseEntity<InfoVo> =
        runtimeConfigService.doDelete(idList).also {
            refreshEventPublish.doNotifyUpdateRuntime()
        }.let {
            ResponseEntity.ok(InfoVo(message = "删除成功"))
        }

    @Operation(summary = "更新指定的参数信息", description = "可更新参数值、描述、状态")
    @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过；配置ID不能为空；找不到信息；"))
    @PreAuthorize(RuntimeConfigExpression.runtimeUpdate)
    @PatchMapping(value = [OauthApi.runtimeConfig], produces = [MediaType.APPLICATION_JSON_VALUE])
    @AcpCloudDuplicateSubmission
    @Throws(WebException::class)
    fun update(@RequestBody @Valid runtimePo: RuntimePo): ResponseEntity<RuntimeConfig> {
        if (CommonTools.isNullStr(runtimePo.id)) {
            throw WebException("配置ID不能为空")
        }
        return runtimeConfigService.doUpdate(runtimePo).also {
            refreshEventPublish.doNotifyUpdateRuntime()
        }.let {
            ResponseEntity.ok(it)
        }
    }

    @Operation(summary = "查询参数信息列表", description = "查询条件：参数名称、值、状态")
    @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过；"))
    @PreAuthorize(RuntimeConfigExpression.runtimeQuery)
    @PostMapping(value = [OauthApi.runtimeConfig], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun query(@RequestBody @Valid runtimeQueryPo: RuntimeQueryPo): ResponseEntity<CustomerQueryPageVo<RuntimeConfig>> =
        ResponseEntity.ok(runtimeConfigService.doQuery(runtimeQueryPo))

    @Operation(summary = "获取参数信息", description = "根据参数名称获取")
    @ApiResponses(ApiResponse(responseCode = "400", description = "找不到参数信息；"))
    @GetMapping(value = [OauthApi.runtimeConfig + "/{name}"], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun find(@PathVariable(name = "name") name: String): ResponseEntity<RuntimeConfigVo> =
        openInnerRuntimeController.find(name)

    @Operation(summary = "获取参数信息", description = "根据参数名称获取")
    @GetMapping(value = [OauthApi.runtimeConfig], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun findList(): ResponseEntity<Map<String, RuntimeConfigVo>> = openInnerRuntimeController.findList()

}
